package com.candy.codegen.controller;


import cn.hutool.core.io.IoUtil;
import com.candy.codegen.domain.*;
import com.candy.codegen.domain.param.GenTableColumnQueryParam;
import com.candy.codegen.domain.param.GenTableQueryParam;
import com.candy.codegen.domain.param.GenTableSaveParam;
import com.candy.codegen.service.GenTableColumnService;
import com.candy.codegen.service.GenTableService;
import com.candy.codegen.domain.vo.GenTableColumnVO;
import com.candy.codegen.domain.vo.GenTableVO;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.Map;

/**
 * 代码生成器控制器
 * @author rong xi
 * @date 2023/09/14 10:27
 * @version 1.0
 */
@Controller
@RequestMapping("/gen")
@AllArgsConstructor
@Validated
public class GenController{
    private final String prefix = "gen/gen-";
    private final GenTableService genTableService;
    private final GenTableColumnService genTableColumnService;


    /**
     * 跳转到代码生成列表页
     * @return 页面路径
     */
    @GetMapping()
    @SuppressWarnings("all")
    public String gen() {
        return prefix + "index";
    }

    /**
     * 跳转到导入表信息页
     * @return 页面路径
     */
    @GetMapping("/import")
    @SuppressWarnings("all")
    public String importTable() {
        return prefix + "import";
    }

    /**
     * 跳转到字段编辑页面
     * @param tableId 表id
     * @param modelMap model数据
     * @return 页面路径
     */
    @GetMapping("/edit/{tableId}")
    @SuppressWarnings("all")
    public String edit(@PathVariable("tableId") Long tableId, ModelMap modelMap) {
        genTableService.getEditInfo(tableId,modelMap);
        return prefix + "edit";
    }

    /**
     * 分页查询表信息
     * @param param 查询条件对象
     * @return 分页对象
     */
    @PostMapping("/page")
    @ResponseBody
    public PageResult<GenTableVO> page(GenTableQueryParam param) {
        return genTableService.page(param);
    }

    /**
     * 查询未导入的表信息
     * @param param 查询条件对象
     * @return table信息
     */
    @PostMapping("/db-page")
    @ResponseBody
    @SuppressWarnings("all")
    public PageResult<GenTableVO> pageDB(GenTableQueryParam param) {
        return genTableService.pageDb(param);
    }

    /**
     * 查询已导入表字段信息
     * @param param 查询条件对象
     * @return table信息
     */
    @PostMapping("/column/list")
    @ResponseBody
    public PageResult<GenTableColumnVO> getTableColumnData(GenTableColumnQueryParam param) {
        return genTableColumnService.getTableColumnData(param);
    }

    /**
     * 导入表及字段信息
     * @param tableNames 表名称
     * @return 操作结果
     */
    @PostMapping("/import-table-save")
    @ResponseBody
    public AjaxResult<?> importGenTable(@NotEmpty String tableNames) {
        genTableService.importGenTable(tableNames);
        return AjaxResult.success();
    }

    /**
     * 保存修改的表信息
     * @param param 表信息
     * @return 操作结果
     */
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult<?> updateGenTable(@Validated GenTableSaveParam param) {
        genTableService.modify(param);
        return AjaxResult.success();
    }

    /**
     * 删除的表信息
     * @param tableIds 表id
     * @return 操作结果
     */
    @PostMapping("/remove")
    @ResponseBody
    public AjaxResult<?> removeGenTable(@NotEmpty String tableIds) {
        genTableService.delete(tableIds);
        return AjaxResult.success();
    }

    /**
     * 预览代码
     * @param tableId 表id
     * @return 操作结果
     */
    @GetMapping("/preview/{tableId}")
    @ResponseBody
    public AjaxResult<?> preview(@PathVariable("tableId") Long tableId){
        Map<String, String> dataMap = genTableService.previewCode(tableId);
        return AjaxResult.success(dataMap);
    }

    /**
     * 生成代码-路径方式生成
     * @param tableId 表id
     * @return 操作结果
     */
    @GetMapping("/generate/{tableId}")
    @ResponseBody
    public AjaxResult<?> generatorCode(@PathVariable("tableId") Long tableId) {
        genTableService.generatorCode(tableId);
        return AjaxResult.success();
    }

    /**
     * 生成代码-下载方式生成
     * @param response 响应
     * @param tableId 表id
     * @throws IOException 异常
     */
    @GetMapping("/download/{tableId}")
    public void downloadCode(HttpServletResponse response, @PathVariable("tableId") Long tableId) throws IOException {
        byte[] data = genTableService.batchDownloadCode(tableId.toString());
        writeResponse(response, data);
    }

    /**
     * 批量下载生成代码
     * @param response 响应
     * @param tableIds 表ids
     * @throws IOException 异常
     */
    @GetMapping("/batch-download-code")
    public void batchDownloadCode(HttpServletResponse response, @NotEmpty String tableIds) throws IOException {
        byte[] data = genTableService.batchDownloadCode(tableIds);
        writeResponse(response, data);
    }

    /**
     * 生成zip文件
     * @param response 响应
     * @param data 文件字节
     * @throws IOException 异常
     */
    private void writeResponse(HttpServletResponse response, byte[] data) throws IOException {
        response.reset();
        response.setHeader("Content-Disposition", "attachment; filename=\"candy-gen-code.zip\"");
        response.addHeader("Content-Length", "" + data.length);
        response.setContentType("application/octet-stream; charset=UTF-8");
        IoUtil.write(response.getOutputStream(),true,data);
    }
}